/************************************************************************/
// Copyright (C) 2016, han_gangbiao. All rights reserved.
// Use of this source code is governed by a GPL-v2 license that can be found in the License file.
// 
// [Time]:      2016-03-20 21:19:21
// [Author]:    han_gangbiao [http://my.oschina.net/jackhen]
// [Info]:      
/************************************************************************/

#include "RpcServerMgr.h"
#include "rpc_server_base.h"

CRpcServerMgr::CRpcServerMgr()
{
    m_netReactor.init_reactor(this, 4);
    m_rpc_servers_map.clear();
    m_kv_map.clear();
}
CRpcServerMgr::CRpcServerMgr(int threadnum)
{
    m_netReactor.init_reactor(this, threadnum);
    m_rpc_servers_map.clear();
    m_kv_map.clear();
}
CRpcServerMgr::~CRpcServerMgr()
{
    m_netReactor.uninit_reactor();
    del_all_rpc_server();
    del_all_kv();
}

void CRpcServerMgr::free()
{
    m_netReactor.uninit_reactor();
    del_all_rpc_server();
    del_all_kv();
}

int CRpcServerMgr::close_fd( SOCK_FD fd )
{
    return m_netReactor.close_fd(fd);
}

smart::ref_ptr<CRpcServerBase> CRpcServerMgr::get_rpc_server( SOCK_FD listenfd )
{
    CRpcServerBase* server = NULL;
    smart::guard_t guard(&m_lock);
    std::map< SOCK_FD, smart::ref_ptr<CRpcServerBase> >::iterator it = m_rpc_servers_map.find(listenfd);
    if( it != m_rpc_servers_map.end() )
    {
        server = (it->second).getPointer();
    }
    return server;
}
int CRpcServerMgr::add_rpc_server( CRpcServerBase* server )
{
    if(server == NULL) return -1;
    smart::guard_t guard(&m_lock);
    std::map< SOCK_FD, smart::ref_ptr<CRpcServerBase> >::iterator it = m_rpc_servers_map.find(server->m_listenfd);
    if( it != m_rpc_servers_map.end() )
    {
        m_rpc_servers_map.erase(it);
    }
    m_rpc_servers_map[server->m_listenfd] = server;
    return 0;
}
int CRpcServerMgr::del_rpc_server( SOCK_FD listenfd )
{
    smart::guard_t guard(&m_lock);
    std::map< SOCK_FD, smart::ref_ptr<CRpcServerBase> >::iterator it = m_rpc_servers_map.find(listenfd);
    if( it != m_rpc_servers_map.end() )
    {
        m_rpc_servers_map.erase(it);
        return 0;
    }
    return -1;
}
void CRpcServerMgr::del_all_rpc_server()
{
    smart::guard_t guard(&m_lock);
    m_rpc_servers_map.clear();
}
    
SOCK_FD CRpcServerMgr::get_listenfd_from_kv( SOCK_FD cli_fd )
{
    SOCK_FD listen_fd = -1;
    smart::guard_t guard(&m_kv_lock);
    std::map< SOCK_FD, SOCK_FD >::iterator it = m_kv_map.find(cli_fd);
    if( it != m_kv_map.end() )
    {
        listen_fd = it->second;
    }
    return listen_fd;
}
int CRpcServerMgr::add_kv( SOCK_FD cli_fd, SOCK_FD listen_fd )
{
    if(cli_fd < 0 || listen_fd < 0) return -1;
    smart::guard_t guard(&m_kv_lock);
    std::map< SOCK_FD, SOCK_FD >::iterator it = m_kv_map.find(cli_fd);
    if( it != m_kv_map.end() )
    {
        m_kv_map.erase(it);
    }
    m_kv_map[cli_fd] = listen_fd;
    return 0;
}
int CRpcServerMgr::del_kv( SOCK_FD cli_fd )
{
    smart::guard_t guard(&m_kv_lock);
    std::map< SOCK_FD, SOCK_FD >::iterator it = m_kv_map.find(cli_fd);
    if( it != m_kv_map.end() )
    {
        m_kv_map.erase(it);
        return 0;
    }
    return -1;
}
void CRpcServerMgr::del_all_kv()
{
    smart::guard_t guard(&m_kv_lock);
    m_kv_map.clear();
}



int CRpcServerMgr::on_connect( SOCK_FD listen_fd, SOCK_FD cli_fd, const char* remote_ip, int remote_port )
{
    int ret = -1;
    add_kv(cli_fd, listen_fd);
    smart::ref_ptr<CRpcServerBase> server = get_rpc_server(listen_fd);
    if(server) {
        ret = server->on_connect(cli_fd, remote_ip, remote_port);
    } else {
        printf("on_connect, but not found in m_rpc_servers_map listen_fd[%d]\n", listen_fd);
    }
    return ret;
}
int CRpcServerMgr::on_data( SOCK_FD fd, const char* data, int len, const char* remote_ip, int remote_port )
{
    SOCK_FD listen_fd = get_listenfd_from_kv(fd);
    smart::ref_ptr<CRpcServerBase> server = get_rpc_server(listen_fd);
    if(server) {
        server->on_data(fd, data, len, remote_ip, remote_port);
    } else {
        printf("on_data, but not found in m_rpc_servers_map listen_fd[%d]\n", listen_fd);
    }
    return 0;
}
int CRpcServerMgr::on_send_ack( SOCK_FD fd, int len )
{
    SOCK_FD listen_fd = get_listenfd_from_kv(fd);
    smart::ref_ptr<CRpcServerBase> server = get_rpc_server(listen_fd);
    if(server) {
        server->on_send_ack(fd, len);
    } else {
        printf("on_send_ack, but not found in m_rpc_servers_map listen_fd[%d]\n", listen_fd);
    }
    return 0;
}
int CRpcServerMgr::on_close( SOCK_FD fd, int error )
{
    printf("CRpcServerMgr::on_close fd = %d\n", fd);
    smart::ref_ptr<CRpcServerBase> lis_server = get_rpc_server(fd); //fd==listenfd
    if(lis_server) {
        printf("CRpcServerMgr::on_close, listen close fd = %d\n", fd);
        lis_server->on_listen_close(fd, error);
        del_rpc_server(fd);
        return 0;
    }
    
    //>fd == cli_fd
    SOCK_FD listen_fd = get_listenfd_from_kv(fd);
    smart::ref_ptr<CRpcServerBase> server = get_rpc_server(listen_fd);
    if(server) {
        server->on_close(fd, error);
    } else {
        printf("CRpcServerMgr::on_close, but not found in m_rpc_servers_map listen_fd[%d]\n", listen_fd);
    }
    del_kv(fd);
    return 0;
}
